import {
  HttpStatus,
  UnprocessableEntityException,
  ValidationError,
  ValidationPipe,
} from '@nestjs/common';
import { NestFactory, Reflector } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express/interfaces';

import { AppModule } from './app.module';
import { ApiExceptionFilter } from './core/filters/api-exception.filter';
import { ApiTransformInterceptor } from './core/interceptors/api-transform.interceptor';
import { setupSwagger } from './setup-swagger';

const SERVER_PORT = process.env.SERVER_PORT;

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);

  // 配置静态资源目录
  // app.useStaticAssets(join(__dirname, '../public/'), {
  //   prefix: '/static',
  // });
  // 跨域
  app.enableCors();
  // 前缀
  app.setGlobalPrefix('api');
  // 验证
  app.useGlobalPipes(
    new ValidationPipe({
      transform: true, // 如果设置为true, ValidationPipe则尝试将传入的数据转换为与DTO相匹配的类型
      whitelist: true, // 如果设置为true, ValidationPipe将只保留DTO中定义的属性, 并过滤掉其他属性
      forbidNonWhitelisted: false, // 是否要禁止传入的数据中包含未在DTO中定义的属性, 如果设置为true, ValidationPipe将抛出一个异常
      errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY,
      exceptionFactory: (errors: ValidationError[]) => {
        return new UnprocessableEntityException(
          errors
            .filter((item) => !!item.constraints)
            .flatMap((item) => Object.values(item.constraints))
            .join('; '),
        );
      },
    }),
  );
  // 错误处理
  app.useGlobalFilters(new ApiExceptionFilter());
  // 返回处理
  app.useGlobalInterceptors(new ApiTransformInterceptor(new Reflector()));
  // 接口文档
  setupSwagger(app);
  // app.useWebSocketAdapter(new WsAdapter(app));

  await app.listen(SERVER_PORT, '0.0.0.0');
  const serverUrl = await app.getUrl();
  console.log(`api服务已经启动,请访问: ${serverUrl}`);
  console.log(`API文档已生成,请访问: ${serverUrl}/${process.env.SWAGGER_PATH}/`);
}
bootstrap();
